home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / scrasm / scroll.doc < prev    next >
Encoding:
Text File  |  1993-03-09  |  15.3 KB  |  297 lines

  1.             ________________________________________________
  2.            |+----------------------------------------------+|
  3.            ||          I N T R O D U C I N G :             ||
  4.            |+----------------------------------------------+|
  5.            ||               Steve's 4-Way                  ||
  6.            ||    ___    ___   ____     ___    _      _     ||
  7.            ||   / __|  / __| |  _ \   / _ \  | |    | |    ||
  8.            ||  | <_   | |    | |_> | | | | | | |    | |    ||
  9.            ||   \_ \  | |    |    /  | | | | | |    | |    ||
  10.            ||   __> | | |__  | |\ \  | |_| | | |__  | |__  ||
  11.            ||  |___/   \___| |_| \_|  \___/  |____| |____| ||
  12.            |+______________________________________________+|
  13.            +------------------------------------------------+
  14.  
  15.   There, now that I have the hype outta the way, let me explain what
  16. this program is.  I'm releasing the source code to my 4-way scrolling
  17. code so that others can learn from it.  There aren't enough really
  18. good resources out there for someone learning to program games, so I'm
  19. trying to do my part to help.
  20.  
  21. WHAT IT IS:
  22.  
  23.   The code is 100% assembly, for which I use MASM 6.0, so there may
  24. be a few problems converting to Turbo Assembler.  I also use the ".386"
  25. directive, meaning that you can't run this code with a 286 or earlier.
  26. But most of the code should be easily convertible.  I haven't been
  27. programming for 386's much so I really don't make the use of the 386
  28. registers like I could have.  Mostly I just did it for some extra 386
  29. instructions.
  30.  
  31.   You'll need a VGA which can support mode 13h, the MCGA mode.  This
  32. code runs in "tweaked" MCGA mode, or what is called "Mode X".  For more
  33. information on Mode X, check out the 1991 - 1992 issues of Doctor Dobbs
  34. Journal, wherein you will find Michael Abrash's excellent Graphics
  35. Programming column.  This is where I (and many others) found out about
  36. Mode X, which is an excellent graphics mode for fast 256-color graphics.
  37. Also, you can take a look at XLIB, YakIcons, FastGraph, etc which are all
  38. graphics libraries (public domain or otherwise) which support Mode X
  39. graphics and probably have some good documentation on programming the mode.
  40. Additionally, check out _The Programmer's Guide to the EGA and VGA Cards_,
  41. by Richard Ferraro, and _Power Graphics Programming_ (out of print, but
  42. available directly from Que Books) by Michael Abrash.  Finally, you can
  43. ask about graphics programming on many newsgroups such as
  44. "rec.games.programmer"...
  45.  
  46. WHAT IT DOES:
  47.  
  48.   The code will allow you to create "tiled" background patterns and then
  49. to omnidirectionally scroll over them.  You could implement sprite routines
  50. and then animate them over the background, but I haven't gotten this far
  51. yet.  The scrolling is always relational -- ie no "jump-to"'s, just "scroll
  52. left", "scroll up", etc.  Jump to would be very easy to implement, I just
  53. haven't done it yet.
  54.  
  55.   It runs at about 60-70 fps on a 386/20, which means that it is operating
  56. in under the time of one vertical refresh (_just_ under, according to some
  57. timing I've done).  This could probably be reduced, but the best way to
  58. reduce it is to limit the speed at which it scrolls -- if you stick to
  59. scrolling at most 8 pixels at a time in two axes or 16 pixels at a time
  60. in one axis, it is very fast.  More than that, and it occasionally takes
  61. more than one refresh period even on my 486.  Still, that should be
  62. fast enough for just about any game.
  63.  
  64.   I also included some routines to generate maps, tiles, and palettes
  65. so you can see the file formats.  These are in C, and the executables
  66. are around in case you don't care to recompile.  None of the utilities
  67. are exactly production quality.  You'll have to look at the code to
  68. figure out the arguments!  Luckily you can just run them with no args
  69. and they perform default behavior.
  70.  
  71.   Lastly, the program SCROLL.EXE is a demo of what it can do.  In this
  72. demo you can use one of two sets of keyboard controls to scroll around.
  73. One, the default set of commands, lets you press up/down/left/right and
  74. scroll in that direction.  The other has "intertia" -- pressing up/down
  75. left/right will accelerate you in that direction.  You'll see what I
  76. mean, just experiment.  You can switch keyhandlers by pressing K.
  77. You can also switch between the diagonal pattern map and a logo map
  78. by pressing M.  (By the way, it will eventually run out of memory loading
  79. the maps and the diagonal map will screw up... don't worry about it,
  80. it'd be fixed if I had more time).  Try it out.
  81.  
  82. CREDIT WHERE CREDIT IS DUE:
  83.  
  84.   People who (unknowingly) helped me out:
  85.  
  86.         Keyboard by Steven Dollins, Brown Computer Group.  From his
  87.                 KEYINT routines, which is an INT 9 handler to let you
  88.                 keep track of many keys being pressed at the same time.
  89.         Graphics, basically, by Michael Abrash, whose Mode X columns
  90.                 influenced me greatly.
  91.         Palette fades and file I/O by the Future Crew.  Thanks for
  92.                 letting out the Mental Surgery code!
  93.         CPU detection by Ray Duncan, taken from one of his books.
  94.  
  95.   Obviously I haven't just pirated the code, it's all from publicly
  96. released source code and I modified it a bit.  But I wouldn't have come
  97. up with this whole thing without those helping hands.  Thanks.
  98.  
  99. HOW IT WORKS:
  100.  
  101.   Here's how the scrolling works.  I'll explain it from a single-page
  102. point of view, although it actually uses several pages of video memory.
  103. The video memory is laid out like this:
  104. ╔════════════════════════════════╤════════════╗ ───
  105. ║                                │ /  /  /  / ║  │
  106. ║                                │/  /  /  /  ║  │
  107. ║                                │  /  /  /  /║  │
  108. ║           Visible page         │ / Not /  / ║  │
  109. ║                                │/ visible/  ║  │
  110. ║                                │  /  /  /  /║ 64K
  111. ║                                │ /  /  /  / ║  │
  112. ╟────────────────────────────────┘/  /  /  /  ║  │
  113. ║  /  /  /  /  /  /  /  /  /  /  /  /  /  /  /║  │
  114. ║ /  /  /  /  /  /  /  /  /  /  /  /  /  /  / ║  │
  115. ║/  /  /  /  /  /  /  /  /  /  /  /  /  /  /  ║  │
  116. ╚═════════════════════════════════════════════╝ ───
  117. In other words, it has a virtual width greater than the actual screen
  118. width, and a virtual height higher than the actual screen height.  The
  119. VGA hardware allows hardware panning around within the virtual area, so
  120. that makes panning much easier:  you only have to draw the information
  121. that is coming on to the screen with each pan.
  122.  
  123. What is Happening:      What the user sees:
  124. ╔════════╤════╗          ┌────────┐
  125. ║     hel│////║          │     hel│           The picture that is
  126. ╟────────┘////║          └────────┘           coming on to the screen
  127. ║/////////////║                               ("hello") appears to
  128. ╚═════════════╝                               the user to be scrolling
  129. ╔═╤═══════╤═══╗          ┌────────┐           left, although it is
  130. ║/│   hell│///║          │    hell│           actually at a stationary
  131. ║/└───────┘///║          └────────┘           location in memory...
  132. ║/////////////║                               Each time the frame moves,
  133. ╚═════════════╝                               it is not necessary to
  134. ╔══╤═══════╤══╗          ┌────────┐           redraw the parts that stay
  135. ║//│  hello│//║          │   hello│           on the screen, just the
  136. ║//└───────┘//║          └────────┘           parts that become visible.
  137. ║/////////////║
  138. ╚═════════════╝
  139.  
  140.   The same works up&down too, or even left/right and up/down at the same
  141. time.  The problem occurs when you scroll enough to hit the edge of the
  142. virtual space.  Luckily, video memory increases and wraps at the right
  143. edge to one line down on the left edge.  So you end up with a situation
  144. like this after scrolling too far right:
  145. ╔══════════════╤════╗ ───
  146. ╟───────┐//////│    ║  │        User sees:
  147. ║       │//////│  Th║  │       ┌───────────┐
  148. ║e quick│//////│    ║ 64K      │           │
  149. ║       │//////└────╢  │       │  The quick│
  150. ╟───────┘///////////║  │       │           │
  151. ║///////////////////║  │       └───────────┘
  152. ╚═══════════════════╝ ───
  153. The wrapping is transparent to the user.  So, it appears that you can
  154. scroll left & right infinitely, by simply always updating the amount of
  155. memory that has scrolled into view.
  156.  
  157.   But what happens when you scroll too far down?  Now Intel segments come
  158. to the rescue!  Because the video memory is 64K, and that is also the
  159. largest amount of memory you can access in a segment, the segment arithmetic
  160. performs the top-to-bottom wrapping for me.  It results in a similar
  161. situation as is pictured above, but with the screen split horizontally
  162. instead of vertically.  Again, it's completely transparent to the user.
  163.  
  164.   One performance optimization that I've done is to organize the background
  165. picture that is being scrolled into quantitized "tiles" -- 16x16 pixels in
  166. area.  This means that you can store a large amount of picture data if that
  167. data is repetitive -- as the backgrounds of many video games are.  This also
  168. helps when figuring out how much new stuff to draw on the screen.  I can wait
  169. until the panning crosses a 16-pixel border, then draw another 16-pixel
  170. strip, and then wait for another tile crossing, etc.  You can see this in
  171. the MAP.INC and SCROLL.INC code.  16x16 pixels also leads to 256-pixel-square
  172. tiles, which is always a convenient number in assembly... it helps out in
  173. several places in the code.
  174.  
  175.   So, the display page is "wandering" around the video memory, only drawing
  176. what is necessary at any time.  Meanwhile you can animate sprites over the
  177. background, etc.  The only problem is that with one page, information is
  178. constantly being drawn to that page and you can never guarantee that it is in
  179. a correct state at the time of a vertical refresh period.  Instead, I actually
  180. use several pages, so that one can be shown while the other is worked on.
  181. This guarantees a perfect picture at any time.  So for now, let's ignore the
  182. scrolling for a second, and talk about the paging, because it's easier to
  183. understand the paging if scrolling isn't happening.
  184.  
  185.   Here's a basic explanation of how the paging works.  I use three separate
  186. pages, a Draw page, a Show page, and a Blank page.  The Show page refers to
  187. the page that is currently showing, the Draw page to the page that is
  188. under construction (to be shown next frame), and the Blank page should always
  189. be maintained as an up-to-date blank background page.  (The Blank page is
  190. useful for sprite programming which I am going to be doing next.)  Each
  191. of the pages is 352x240, although the screen resolution is only 320x200.
  192.  
  193.   Each frame, the pages rotate DrawPage->ShowPage->BlankPage->DrawPage.
  194. This means that at the beginning of the frame, the Draw Page is already
  195. blank, so all that is necessary is to draw on a bunch of sprites.  The
  196. BlankPage, though, is no longer blank (it's still got stuff from what
  197. was the ShowPage) so we have to erase it, by blanking out the sprites
  198. (luckily the new DrawPage _is_ empty, so we can use a Mode X 32-bit video-
  199. to-video copy to blank it).  Hope you're still with me.
  200.  
  201.   So, this loop continues with each frame, and the loop invariants are
  202. maintained:  Show Page is always a "good" frame -- don't touch it.  Blank
  203. Page is always blank.  Draw Page can look like anything.  Now to include
  204. the scrolling again:
  205.  
  206.   The way I do scrolling with several pages is that the pages ALL wander
  207. around video memory, only they're smaller (1/3 of the size that they could
  208. have been, to be exact!).  Here's a picture of the situation at its worst:
  209. ╔══════════════╗ ───
  210. ║  │//└────────║  │
  211. ║──┘///////////║  │
  212. ║/////┌────────║  │
  213. ║──┐//│PAGE 0  ║  │
  214. ║  │//│ (Draw) ║  │
  215. ║  │//└────────║  │
  216. ║──┘///////////║ 64K
  217. ║/////┌────────║ (21K each page)
  218. ║──┐//│PAGE 1  ║  │
  219. ║  │//│ (Show) ║  │
  220. ║  │//└────────║  │
  221. ║──┘///////////║  │
  222. ║/////┌────────║  │
  223. ║──┐//│PAGE 2  ║  │
  224. ║  │//│ (Blank)║  │
  225. ╚══════════════╝ ───
  226. The pages always maintain an equal distance apart as they wander.  Since
  227. all pages move in parallel, the way it used to work is that as soon as the
  228. pages scrolled, I would draw the newly-visible picture information on
  229. all three of the pages.  This worked great, except that it resulted in
  230. a slight pause every time the screen scrolled because it was doing hardware
  231. pan most of the time (which is very fast) and the drawing routines were
  232. slow.  Now, I've spread the copying over successive frames to allow a
  233. smoother scrolling rate.  This is possible because it's not really necessary
  234. to draw the new information to a page before that page becomes the show
  235. page...
  236.  
  237.   I hope that this has made some sense.  It's pretty complicated stuff.
  238. Take a look at the code and maybe that will help.  Or, write me mail
  239. (my email address is below).  Or, design your own way and ignore this
  240. whole thing.
  241.  
  242. COMING SOON:
  243.  
  244.   Next up are Sprite routines.  I threw in what I started as SPRITE.INC,
  245. although it's not included in the project right now.
  246.   Sound support
  247.  
  248.   Who knows what else?  Depends on what people send me!
  249.  
  250. -------------------------------------------------------------------------
  251.                            R E A D   T H I S
  252. -------------------------------------------------------------------------
  253.                            R E A D   T H I S
  254. -------------------------------------------------------------------------
  255.  
  256.   This code is being released as "SwapWare".  That means that if you wanted
  257. to go ahead and use my code directly, I really wouldn't care.  But I ask
  258. that you send me some of your code that you think is neat.  Especially if
  259. it's modifications that you make to this code, such as quick sprite drawing
  260. or optimizations.
  261.  
  262.   I'm not going to brag and say that I "threw this together in a few hours".
  263. I didn't, it took me many days of work to get it working properly.  But
  264. I'm also not looking for money as recompensation for my labor.  I make
  265. great money at my real day job and you probably have a better use for your
  266. donations, such as legitimizing your unregistered shareware and pirated
  267. games.  I'm in this for the knowledge ... so my best payback would be to
  268. get lots of code from people out there, stuff to really help make a great
  269. game.  In particular, these would be great:
  270.         * 32-bit code
  271.         * Tricky optimizations
  272.         * Fast BitBlt/masked BitBlt code
  273.         * Useful File I/O functions
  274.         * 3D polygon and texture mapping code
  275.         * Maintenance routines -- like numeric conversions, etc.
  276.         * Hardware access code like timing routines and interrupt
  277.           handlers
  278. Any of those would be very helpful when writing a fast scrolling game.
  279.  
  280. You can contact me (for the rest of this term only) at
  281.         seisner@athena.mit.edu
  282. Feel free to ask any questions you want!  I check my mail about once or
  283. twice a week so don't expect instant turnaround...  If you're desperate
  284. to talk to me, say if you work at Origin and want to give me the source
  285. code to Strike Commander or whatnot, you can also reach me at:
  286.         Steve Eisner
  287.         (617) 247-8691
  288. and leave a message.  But I'd rather you wrote e-mail.
  289.  
  290.                                         Thanks,
  291.                                            Steve Eisner
  292.  
  293. *  Read rec.games.programmer!   And for those who already do:
  294.    I dream of a world where no one argues over why Wolfenstein
  295.    3-D sucks or why it doesn't.  Would people just give it a
  296.    break?
  297.